----------------------------------------------------------------------------------
-- Company: 
-- Engineer: 
-- 
-- Create Date:    14:33:38 09/24/2013 
-- Design Name: 
-- Module Name:    multiplier_32 - Behavioral 
-- Project Name: 
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity multiplier_32 is
    Port ( clock : in STD_LOGIC;
			  a : in  STD_LOGIC_VECTOR (31 downto 0);
           b : in  STD_LOGIC_VECTOR (31 downto 0);
           output : out  STD_LOGIC_VECTOR (63 downto 0));
end multiplier_32;

architecture Behavioral of multiplier_32 is
	component adder_32 
		 Port ( a : in  STD_LOGIC_VECTOR (31 downto 0);
				  b : in  STD_LOGIC_VECTOR (31 downto 0);
				  carryIn : in  STD_LOGIC;
				  sum : out  STD_LOGIC_VECTOR (31 downto 0);
				  carryOut : out  STD_LOGIC);
	end component;
	
	component d_flip_flop is
		 Port ( 	clock : in  STD_LOGIC;
					reset : in  STD_LOGIC;
					input : in  STD_LOGIC;
					output : out  STD_LOGIC);
	end component;
	
	component multiplier_process is
		 Port ( clock : in STD_LOGIC;
				  a : in  STD_LOGIC_VECTOR (31 downto 0);
				  b : in  STD_LOGIC_VECTOR (31 downto 0);
				  carry: in STD_LOGIC;
				  sumIn : in  STD_LOGIC_VECTOR (31 downto 0);
				  sumOut : out  STD_LOGIC_VECTOR (63 downto 0);
				  addItemOne: out STD_LOGIC_VECTOR (31 downto 0);
				  addItemTwo: out STD_LOGIC_VECTOR (31 downto 0);
				  counterValue : in STD_LOGIC_VECTOR (4 downto 0);
				  counterReset : out STD_LOGIC);
	end component;
	
	signal sumTransfer : STD_LOGIC_VECTOR (31 downto 0) := (others => '0');
	signal sum : STD_LOGIC_VECTOR (63 downto 0) := (others => '0');
	signal counterReset: STD_LOGIC := '1';
	signal counter: STD_LOGIC_VECTOR (4 downto 0) := (others => '0');
	signal flipflopInput : STD_LOGIC_VECTOR (2 downto 0) := (others => '0');
	signal addPortion: STD_LOGIC_VECTOR (31 downto 0) := (others => '0');
	signal addPortion2 : STD_LOGIC_VECTOR (31 downto 0) := (others => '0');
	signal newCarry: STD_LOGIC := '0';
begin
	flip_flop_l1: d_flip_flop port map(clock => clock,
												  reset => counterReset,
												  input => '1',
												  output => counter(0));
	flip_flop_l2: d_flip_flop port map(clock => clock,
												  reset => counterReset,
												  input => counter(0),
												  output => counter(1));
	flip_flop_l3: d_flip_flop port map(clock => clock,
												  reset => counterReset,
												  input => flipflopInput(2),
												  output => counter(2));
	flip_flop_l4: d_flip_flop port map(clock => clock,
												  reset => counterReset,
												  input => flipflopInput(1),
												  output => counter(3));
	flip_flop_l5: d_flip_flop port map(clock => clock,
												  reset => counterReset,
												  input => flipflopInput(0),
												  output => counter(4));
	adder : adder_32 port map ( a => addPortion,
										 b => addPortion2,
										 carryIn => '0',
										 sum => sumTransfer,
										 carryOut => newCarry);
	
	action : multiplier_process port map ( clock => clock,
														a => a,
														b => b,
														carry => newCarry,
														sumIn => sumTransfer,
														sumOut => sum,
														addItemOne => addPortion,
														addItemTwo => addPortion2,
														counterValue => counter,
														counterReset => counterReset);

output <= sum;
flipflopInput <= (counter(0) and counter(1)) & (counter(0) and counter(1) and counter(2)) & (counter(0) and counter(1) and counter(2) and counter(3));

end Behavioral;

